/*
RetroLeague - Mobile application for The Retro League Podcast
Copyright (C) 2010-2012 Hugues Johnson

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

package com.huguesjohnson.retroleague;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import com.huguesjohnson.retroleague.episode.Episode;
import com.huguesjohnson.retroleague.util.HttpFetch;
import com.huguesjohnson.retroleague.util.SerializationHelper;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class NowPlayingActivity extends Activity{
	private final static String TAG="NowPlayingActivity";
	//ui stuff
	private AlertDialog aboutDialog;
	private ImageView imageViewNowPlayingEpisodeLogo;
	private TextView textViewNowPlayingEpisodeSummary;
	private TextView textViewEpisodeLinks;
	private Button downloadButton;
	//menu constants
	private final static int MENU_ABOUT=0;
	private final static int MENU_BACK=1;
	
	private class DownloadEpisodeLogoTask extends AsyncTask<String,String,Bitmap>{
		public Bitmap doInBackground(String... params){
			try{
				String imageUrl=EpisodeListActivity.getSelectedEpisode().getImageUrl();
				Log.d(TAG,"DownloadEpisodeLogoTask.doInBackground, imageUrl="+imageUrl);
				Bitmap bitmap=ImageCache.get(imageUrl);
				if(bitmap!=null){return(bitmap);}
        		long startTime=System.currentTimeMillis();
				bitmap=HttpFetch.fetchBitmap(imageUrl);
        		long endTime=System.currentTimeMillis();
        		Log.d(TAG,"DownloadEpisodeLogoTask.doInBackground, Time to fetch bitmap="+(endTime-startTime)+"ms");
				ImageCache.put(imageUrl,bitmap);
                return(bitmap);				
			}catch(Exception x){
				Log.e(TAG,"DownloadEpisodeLogoTask",x);
    	    	return(null);
			}
	     }

	     public void onPostExecute(Bitmap result){
	    	 imageViewNowPlayingEpisodeLogo.setImageBitmap(result);
	     }
	 }
	
	private class SetEpisodeSummaryTask extends AsyncTask<String,String,String>{
		public String doInBackground(String... params){
			return(EpisodeListActivity.getSelectedEpisode().getEpisodeSummary());
	     }

	     public void onPostExecute(String result){
	 		textViewNowPlayingEpisodeSummary.setText(result);
	     }
	 }
	
	private class SetEpisodeLinksTask extends AsyncTask<String,String,String>{
		public String doInBackground(String... params){
			return(EpisodeListActivity.getSelectedEpisode().getLinksHtml());
	     }

	     public void onPostExecute(String result){
			textViewEpisodeLinks.setText(Html.fromHtml(result));     
	     }
	 }
	
	private class DownloadEpisodeTask extends AsyncTask<String,Integer,Void>{
		private ProgressBar progressBar;
		private String downloadPath;
		private boolean downloadSuccessful;
		private Exception x;
		
		@Override
		protected void onPreExecute(){
			downloadButton.setClickable(false);
			downloadButton.setEnabled(false);
			progressBar=(ProgressBar)findViewById(R.id.ProgressBarDownloadEpisode);
			progressBar.setVisibility(View.VISIBLE);
		}

		@Override
		protected Void doInBackground(String... params){
			HttpURLConnection urlConnection=null;
			FileOutputStream out=null;
			InputStream in=null;
			try{
				Episode episode=EpisodeListActivity.getSelectedEpisode();
				int enclosureLength=episode.getEnclosureLength();
				progressBar.setMax(enclosureLength);
				if(SerializationHelper.checkMediaState()){
					String fileName=episode.getDownloadUrl();
					int startIndex=fileName.lastIndexOf("/")+1;
					int endIndex=fileName.lastIndexOf("?");
					if(endIndex>startIndex){
						fileName=fileName.substring(startIndex,endIndex);
					}else{
						fileName=fileName.substring(startIndex);
					}
					Log.d(TAG,"DownloadEpisodeTask.doInBackground - fileName="+fileName);
					File destinationDir=new File(Environment.getExternalStorageDirectory().getPath()+"/RetroLeagueDownloads");
					if(!destinationDir.exists()){
						boolean success=destinationDir.mkdirs();
						Log.d(TAG,"DownloadEpisodeTask.doInBackground - result of destinationDir.mkdirs() is "+success);
					}
					downloadPath=destinationDir+"/"+fileName;
					Log.d(TAG,"DownloadEpisodeTask.doInBackground - downloadPath="+downloadPath);
		            URL url=new URL(episode.getDownloadUrl());
		            urlConnection=(HttpURLConnection)url.openConnection();
		            urlConnection.setRequestMethod("GET");
		            urlConnection.setDoOutput(true);
		            urlConnection.connect();
		            File f=new File(downloadPath);
		            if(f.exists()){
		            	if(f.length()>=enclosureLength){
		            		throw(new Exception("Hey, you already downloaded "+downloadPath));
		            	}
		            }else{
		            	boolean success=f.createNewFile();
						Log.d(TAG,"DownloadEpisodeTask.doInBackground - result of f.createNewFile() is "+success);
		            }
		            out=new FileOutputStream(f);
		            in=urlConnection.getInputStream();
					Log.d(TAG,"DownloadEpisodeTask.doInBackground - urlConnection.getInputStream() was successful");
		            byte[] buffer=new byte[1024];
		            int bytes=0;
		            int progress=0;
		            while((bytes=in.read(buffer))>0){
		                out.write(buffer,0,bytes);
		                progress+=1024;
		                this.publishProgress(progress);
		            }
					downloadSuccessful=true;
				}else{
					throw(new Exception("Unable to access SD card"));
				}
			}catch(Exception x){
				downloadSuccessful=false;
				this.x=x;
			}finally{
				if(out!=null){
					try{out.close();}catch(IOException iox){Log.e(TAG,"DownloadEpisodeTask.doInBackground - try{out.close();}",iox);}
				}
				if(in!=null){
					try{in.close();}catch(IOException iox){Log.e(TAG,"DownloadEpisodeTask.doInBackground - try{in.close();}",iox);}
				}
				if(urlConnection!=null){
					try{urlConnection.disconnect();}catch(Exception x){Log.e(TAG,"DownloadEpisodeTask.doInBackground - try{urlConnection.disconnect()}",x);}
				}
			}
			return(null);
		}

		@Override
		protected void onProgressUpdate(Integer... values){
			progressBar.setProgress(values[0].intValue());
		}
		
		@Override
		protected void onPostExecute(Void result){
			progressBar.setVisibility(View.GONE);
			downloadButton.setClickable(true);
			downloadButton.setEnabled(true);
			//show a message to say where it went
			if(downloadSuccessful){
				showInfoDialog("Successfully downloaded episode to "+downloadPath);
			}else{
				if(this.x==null){
					this.x=new Exception("Unable to download to "+downloadPath);
				}
				showErrorDialog(this.x);
			}
		}
	}
	
	OnClickListener playButtonListener=new OnClickListener(){
		@Override
		public void onClick(View v){
			try{
				Uri uri=Uri.parse(EpisodeListActivity.getSelectedEpisode().getDownloadUrl());
				Intent intent=new Intent(Intent.ACTION_VIEW,uri);
				startActivity(intent);
			}catch(Exception x){
				showErrorDialog(x);
			}
		}
	};
	
	OnClickListener downloadButtonListener=new OnClickListener(){
		@Override
		public void onClick(View v){
			new DownloadEpisodeTask().execute("");
		}
	};
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu){
		try{
			menu.add(0,MENU_ABOUT,0,"About").setIcon(R.drawable.menu_about);
			menu.add(0,MENU_BACK,1,"Back to episode list").setIcon(R.drawable.menu_back);
			return(true);
		}catch(Exception x){
			Log.e(TAG,"onCreateOptionsMenu",x);
			return(false);
		}
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item){
		try{
			switch(item.getItemId()){
			case MENU_BACK:{
				this.finish();
				return(true);
			}
			case MENU_ABOUT:{
				this.showAboutDialog();
				return(true);
			}
			default:{return(false);}
			}
		}catch(Exception x){
			if(item!=null){
				Log.e(TAG,"onOptionsItemSelected: item.getItemId()="+item.getItemId(),x);
			}else{
				Log.e(TAG,"onOptionsItemSelected: item is null",x);
			}
			return(false);
		}
	}

	@Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        try{
	        setContentView(R.layout.nowplayinglayout);
			this.imageViewNowPlayingEpisodeLogo=(ImageView)findViewById(R.id.ImageViewNowPlayingEpisodeLogo);
			//setup play button
			Button playButton=(Button)findViewById(R.id.ButtonPlay);
			playButton.setOnClickListener(playButtonListener);
			//setup download button
			this.downloadButton=(Button)findViewById(R.id.ButtonDownload);
			downloadButton.setOnClickListener(downloadButtonListener);
			//set textViewNowPlayingEpisodeSummary
			this.textViewNowPlayingEpisodeSummary=(TextView)findViewById(R.id.TextViewNowPlayingEpisodeSummary);
			//link movement for episode links
			this.textViewEpisodeLinks=(TextView)findViewById(R.id.TextViewEpisodeLinks);
			this.textViewEpisodeLinks.setMovementMethod(LinkMovementMethod.getInstance());
        }catch(Exception x){
        	this.showErrorDialog(x);
        }
	}
    
	@Override
	protected void onResume(){
		super.onResume();
		//image
		new DownloadEpisodeLogoTask().execute("");
		//summary
		new SetEpisodeSummaryTask().execute("");
		//links
		new SetEpisodeLinksTask().execute("");
		//title
		TextView textViewNowPlayingEpisodeTitle=(TextView)findViewById(R.id.TextViewNowPlayingEpisodeTitle);
		textViewNowPlayingEpisodeTitle.setText(EpisodeListActivity.getSelectedEpisode().getTitle());
	}
	
	private void showAboutDialog(){
		try{
			//create the dialog
			if(this.aboutDialog==null){
				LayoutInflater inflater=(LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
				View layout=inflater.inflate(R.layout.aboutdialoglayout,(ViewGroup)findViewById(R.id.AboutDialogRoot));
				AlertDialog.Builder builder=new AlertDialog.Builder(this);
				builder.setView(layout);
				builder.setTitle("About");
				builder.setPositiveButton("Close",null);
				this.aboutDialog=builder.create();
			}
			//show the dialog
			this.aboutDialog.show();
		}catch(Exception x){
			Log.e(TAG,"showAboutDialog",x);
		}	
	}
	
	private void showInfoDialog(String message){
		try{
	        new AlertDialog.Builder(this)
	   		.setTitle(R.string.app_name)
	   		.setMessage(message)
	   		.setPositiveButton("That's great!", null)
	   		.show();	
		}catch(Exception x){
			Log.e(TAG,"showInfoDialog",x);
		}
	}
	
	private void showErrorDialog(Exception x){
		try{
	        new AlertDialog.Builder(this)
	   		.setTitle(R.string.app_name)
	   		.setMessage(x.getMessage())
	   		.setPositiveButton("Close", null)
	   		.show();	
		}catch(Exception reallyBadTimes){
			Log.e(TAG,"showErrorDialog",reallyBadTimes);
		}
	}
}